"""
测试文件
"""

from Decos import complete, lprof, mprof, path_knight
from tqdm import tqdm
import pandas as pd
import random
import os

PATH = "out"
music_path = "E:/Music/Minstrel - eyecatch!.mp3"


class ResourceEater:
    path = PATH + "/"

    def __init__(self, is_test=0):
        """
        生成测试用例
        :param is_test: 0 随机生成测试用例； 1 使用已有用例
        """
        random.seed(1)
        self.p = [random.randint(10000, 100000) for i in range(3)] if not is_test else [12321, 35897, 86421]
        self.io = [random.randint(10000, 20000) for i in range(3)] if not is_test else [11111, 12321, 18888]
        self.b = [(random.randint(100, 200), random.randint(100, 200)) for i in range(3)] if not is_test else [(100, 150), (150, 100), (173, 173)]

    @staticmethod
    @lprof(path)
    def lpf(num):
        """
        使用埃氏筛法进行质因数分解
        :param num: 待分解的数字
        :return: 分解的结果，每个元素都是二元组，第一个是质因数，第二个是幂次
        """
        if num >= 2 and type(num) == int:
            f = [0 if i > 2 and not i % 2 else 1 for i in range(num + 1)]
            i = 3
            while i * i <= num:
                if f[i]:
                    for j in range(i + 1, num + 1):
                        if not j % i:
                            f[j] = 0
                i += 1

            factors = [i for i in range(2, num + 1) if f[i]]
            n = num
            result = []

            for factor in factors:
                count = 0
                while not n % factor:
                    count += 1
                    n = n // factor
                if count:
                    result.append((factor, count))
            return result
        else:
            raise Exception("类型或取值错误")

    @staticmethod
    @lprof(path)
    def liotrash(num):
        """
        频繁写文件，写入数字，最后删除
        :param num: 写入次数
        """
        for i in tqdm(range(num)):
            with open(f'trash{num}.txt', 'a', encoding='utf8') as f:
                f.write(str(i) + "\n")
            if i == num - 1:
                print(i)
        else:
            os.remove(f'trash{num}.txt')

    @staticmethod
    @lprof(path)
    def lbigarbage(row, col):
        """
        生成pandas数据框，并打印元素总数
        :param row: 行数
        :param col: 列数
        """
        n = row * col
        data = {i: [j for j in range(i * col, (i + 1) * col)] for i in range(row)}
        df = pd.DataFrame(data)
        print(n)

    @staticmethod
    @mprof(path)
    def mpf(num):
        """
        使用埃氏筛法进行质因数分解
        :param num: 待分解的数字
        :return: 分解的结果，每个元素都是二元组，第一个是质因数，第二个是幂次
        """
        if num >= 2 and type(num) == int:
            f = [0 if i > 2 and not i % 2 else 1 for i in range(num + 1)]
            i = 3
            while i * i <= num:
                if f[i]:
                    for j in range(i + 1, num + 1):
                        if not j % i:
                            f[j] = 0
                i += 1

            factors = [i for i in range(2, num + 1) if f[i]]
            n = num
            result = []

            for factor in factors:
                count = 0
                while not n % factor:
                    count += 1
                    n = n // factor
                if count:
                    result.append((factor, count))
            return result
        else:
            raise Exception("类型或取值错误")

    @staticmethod
    @mprof(path)
    def miotrash(num):
        """
        频繁写文件，写入数字，最后删除
        :param num: 写入次数
        """
        for i in tqdm(range(num)):
            with open(f'trash{num}.txt', 'a', encoding='utf8') as f:
                f.write(str(i) + "\n")
            if i == num - 1:
                print(i)

    @staticmethod
    @mprof(path)
    def mbigarbage(row, col):
        """
        生成pandas数据框，并打印元素总数
        :param row: 行数
        :param col: 列数
        """
        n = row * col
        data = {i: [j for j in range(i * col, (i + 1) * col)] for i in range(row)}
        df = pd.DataFrame(data)
        print(n)


@complete(music_path)
@path_knight(PATH)
def test():
    e = ResourceEater(is_test=1)
    for i in range(1):
        e.lpf(e.p[i])
        e.liotrash(e.io[i])
        e.lbigarbage(*e.b[i])
        e.mpf(e.p[i])
        e.miotrash(e.io[i])
        e.mbigarbage(*e.b[i])


if __name__ == '__main__':
    os.system("del /q /s *.log")
    test()
